<script>
import { getCell, getColumnByCell, getRowIdentity } from 'element-ui/packages/table/src/util'

import { SlickList, SlickItem } from 'vue-slicksort'

export default {
  name: 'HgSortBody',

  components: {
    SlickList, SlickItem
  },

  props: {
    store: {
      required: true
    },
    stripe: Boolean,
    context: {},
    rowClassName: [String, Function],
    rowStyle: [Object, Function],
    fixed: String,
    highlight: Boolean
  },

  render (h) {
    const columnsHidden = this.columns.map((column, index) => this.isColumnHidden(index))

    return (
      <slick-list lockToContainerEdges
        class="hg-sort-table-container"
        lockAxis="y"

        transitionDuration={0}
        draggedSettlingDuration={0}
        pressDelay={0}
        pressThreshold={0}
        distance={0}

        value={this.sortRows}
        on-input={this.sortInput}
        on-sort-start={this.sortStart}
        on-sort-end={this.sortEnd}
        style={this.bodyStyle}
      >
        {
          this._l(this.sortRows, (row, $index) => {
            const rowKey = this.table.rowKey ? this.getKeyOfRow(row, $index) : $index
            const treeNode = this.treeData[rowKey]
            let rowClass = ''
            if (this.highlight && $index === this.oldRowIndex) {
              rowClass = 'current-row'
            }
            const tr = (
              <slick-item class="hg-sort-table-item" index={$index} key={$index}>
                <table style="width: 100%;" cellspacing="0">
                  <tr
                    v-show={treeNode ? treeNode.display : true}
                    style={this.rowStyle ? this.getRowStyle(row, $index) : null}
                    key={rowKey}
                    class={rowClass}>
                    {
                      this._l(this.columns, (column, cellIndex) => {
                        const { rowspan, colspan } = this.getSpan(row, column, $index, cellIndex)
                        if (!rowspan || !colspan) {
                          return ''
                        } else {
                          const columnData = { ...column }
                          if (colspan !== 1) {
                            columnData.realWidth = columnData.realWidth * colspan
                          }
                          const data = {
                            store: this.store,
                            _self: this.context || this.table.$vnode.context,
                            column: columnData,
                            row,
                            $index
                          }
                          if (cellIndex === this.firstDefaultColumnIndex && treeNode) {
                            data.treeNode = {
                              hasChildren: treeNode.hasChildren || (treeNode.children && treeNode.children.length),
                              expanded: treeNode.expanded,
                              indent: treeNode.level * this.treeIndent,
                              level: treeNode.level,
                              loaded: treeNode.loaded,
                              rowKey
                            }
                          }
                          return (
                            <td
                              width={column.width}
                            >
                              {
                                column.renderCell.call(
                                  this._renderProxy,
                                  h,
                                  data,
                                  columnsHidden[cellIndex]
                                )
                              }
                            </td>
                          )
                        }
                      })
                    }
                  </tr></table></slick-item>)

            return tr
          })
        }
      </slick-list>

    )
  },

  computed: {

    table () {
      return this.$parent
    },

    data () {
      return this.store.states.data
    },

    treeData () {
      return this.store.states.treeData
    },

    columnsCount () {
      return this.store.states.columns.length
    },

    leftFixedLeafCount () {
      return this.store.states.fixedLeafColumnsLength
    },

    rightFixedLeafCount () {
      return this.store.states.rightFixedLeafColumnsLength
    },

    leftFixedCount () {
      return this.store.states.fixedColumns.length
    },

    rightFixedCount () {
      return this.store.states.rightFixedColumns.length
    },

    columns () {
      return this.store.states.columns
    },

    hasExpandColumn () {
      return this.columns.some(({ type }) => type === 'expand')
    },

    firstDefaultColumnIndex () {
      for (let index = 0; index < this.columns.length; index++) {
        if (this.columns[index].type === 'default') {
          return index
        }
      }
      return 0
    },

    treeIndent () {
      return this.store.states.indent
    }
  },

  watch: {

  },

  data () {
    return {
      tooltipContent: '',

      sortRows: []
    }
  },

  created () {
    // this.sortRows = this.data;
  },

  methods: {

    setStyle (style) {
      this.bodyStyle = style
      // //console.log(this.bodyStyle)
    },
    setData (data) {

      this.sortRows = data

    },

    getData () {
      return this.sortRows
    },

    sortStart (event) {
      var index = event.index

      var hasChange = true
      if (this.oldRowIndex && this.oldRowIndex === index) {
        hasChange = false
      }

      // //console.log(index + ':' + this.oldRowIndex);

      if (hasChange) {
        var row = this.sortRows[index]
        var oldRow = this.sortRows[this.oldRowIndex]
        this.table.$emit('current-change', row, oldRow)
        // //console.log('change')
      }

      this.oldRowIndex = index

      // //console.log('sortStart: \t\t' + new Date().getTime())
      // //console.log(this.highlight, 'highlight')
    },

    sortEnd ({ event, newIndex, oldIndex, collection }) {
      // var index = event.index;
      // //console.log(event)
      // //console.log(newIndex, 'newIndex sort end ')
      // //console.log(oldIndex, 'oldIndex sort end ')
      this.oldRowIndex = newIndex

      // //console.log('sortEnd: \t\t' + new Date().getTime())
    },

    sortInput (vals) {
      // //console.log('sortInput  1: \t' + new Date().getTime())

      this.sortRows = vals
      // //console.log('sortInput  2:\t' + new Date().getTime())

      // //console.log(vals)
      this.table.$emit('sort-end', this.sortRows)
    },

    getKeyOfRow (row, index) {
      const rowKey = this.table.rowKey
      if (rowKey) {
        return getRowIdentity(row, rowKey)
      }
      return index
    },

    isColumnHidden (index) {

    },

    getSpan (row, column, rowIndex, columnIndex) {
      let rowspan = 1
      let colspan = 1

      const fn = this.table.spanMethod
      if (typeof fn === 'function') {
        const result = fn({
          row,
          column,
          rowIndex,
          columnIndex
        })

        if (Array.isArray(result)) {
          rowspan = result[0]
          colspan = result[1]
        } else if (typeof result === 'object') {
          rowspan = result.rowspan
          colspan = result.colspan
        }
      }

      return {
        rowspan,
        colspan
      }
    },

    getRowStyle (row, rowIndex) {
      const rowStyle = this.table.rowStyle
      if (typeof rowStyle === 'function') {
        // eslint-disable-next-line no-useless-call
        return rowStyle.call(null, {
          row,
          rowIndex
        })
      }
      return rowStyle
    },

    getRowClass (row, rowIndex) {
      const classes = ['el-table__row']
      if (this.highlight) {
        classes.push('current-row')
      }

      return classes
    },

    getCellStyle (rowIndex, columnIndex, row, column) {
      const cellStyle = this.table.cellStyle
      if (typeof cellStyle === 'function') {
        return cellStyle.call(null, {
          rowIndex,
          columnIndex,
          row,
          column
        })
      }
      return cellStyle
    },

    getCellClass (rowIndex, columnIndex, row, column) {
      const classes = [column.id, column.align, column.className]

      if (this.isColumnHidden(columnIndex)) {
        classes.push('is-hidden')
      }

      const cellClassName = this.table.cellClassName
      if (typeof cellClassName === 'string') {
        classes.push(cellClassName)
      } else if (typeof cellClassName === 'function') {
        classes.push(cellClassName.call(null, {
          rowIndex,
          columnIndex,
          row,
          column
        }))
      }

      return classes.join(' ')
    },

    handleCellMouseEnter (event, row) {

    },

    handleCellMouseLeave (event) {

    },

    handleMouseEnter (index) {
      this.store.commit('setHoverRow', index)
    },

    handleMouseLeave () {
      this.store.commit('setHoverRow', null)
    },

    handleContextMenu (event, row) {
      this.handleEvent(event, row, 'contextmenu')
    },

    handleDoubleClick (event, row) {
      this.handleEvent(event, row, 'dblclick')
    },

    handleClick (event, row) {
      // //console.log('sdfadfs')

      this.store.commit('setCurrentRow', row)
      this.handleEvent(event, row, 'click')
    },

    handleEvent (event, row, name) {
      const table = this.table
      const cell = getCell(event)
      let column
      if (cell) {
        column = getColumnByCell(table, cell)
        if (column) {
          table.$emit(`cell-${name}`, row, column, cell, event)
        }
      }
      table.$emit(`row-${name}`, row, column, event)
    },

    handleExpandClick (row, e) {
      e.stopPropagation()
      this.store.toggleRowExpansion(row)
    }
  }
}
</script>
